//
// Created by SongpingWang on 2025/2/8.
//

#ifndef YOLOV11_CPP_UTILS_H
#define YOLOV11_CPP_UTILS_H

#include <iostream>
#include <vector>
#include <cmath>
#include <fstream>
#include <sstream>
#include <string>
#include <cctype>
#include <filesystem>
#include <unordered_map>





using str2str = std::unordered_map<std::string, std::string>;


std::string trim(const std::string& str) {
    size_t first = str.find_first_not_of(' ');
    size_t last = str.find_last_not_of(' ');
    return (first == std::string::npos) ? "" : str.substr(first, last - first + 1);
}





// 函数用于解析ini文件
std::unordered_map<std::string, str2str> load_config(const std::string& config_file) {
    std::unordered_map<std::string, str2str> config;
    std::ifstream file(config_file);

    if (!file.is_open()) {
        throw std::runtime_error("Failed to open '" + config_file + "'");
    }

    std::string line;
    std::string current_section;

    while (std::getline(file, line)) {
        line = trim(line);

        if (line.empty() || line[0] == ';' || line[0] == '#') {
            continue;
        }

        if (line[0] == '[' && line.back() == ']') {
            current_section = line.substr(1, line.size() - 2);
            continue;
        }

        size_t delimiter_pos = line.find('=');
        if (delimiter_pos != std::string::npos) {
            std::string key = trim(line.substr(0, delimiter_pos));
            std::string value = trim(line.substr(delimiter_pos + 1));
            config[current_section][key] = value;
        }
    }

    file.close();
    return config;
}


/*

// 函数用于去除字符串两端的空白字符（包括空格和制表符）
std::string trim_s_tb(const std::string& str) {
    size_t first = str.find_first_not_of(" \t");
    if (first == std::string::npos) return "";
    size_t last = str.find_last_not_of(" \t");
    return str.substr(first, (last - first + 1));
}

// 函数用于解析YAML文件
std::unordered_map<std::string, std::string> parseYAML(const std::string& filePath) {
    std::unordered_map<std::string, std::string> yamlData;
    std::ifstream file(filePath);

    if (!file.is_open()) {
        std::cerr << "无法打开文件: " << filePath << std::endl;
        return yamlData;
    }

    std::string line;
    std::vector<std::pair<std::string, int>> contextStack; // 保存父键和对应的缩进级别

    while (std::getline(file, line)) {
        // 计算缩进级别（前导空格或制表符的数量）
        size_t indent = 0;
        while (indent < line.size() && (line[indent] == ' ' || line[indent] == '\t')) {
            ++indent;
        }
        std::string content = line.substr(indent);
        content = trim_s_tb(content);

        if (content.empty() || content[0] == '#') continue;

        size_t colonPos = content.find(':');
        if (colonPos != std::string::npos) {
            std::string key = trim_s_tb(content.substr(0, colonPos));
            std::string value = trim_s_tb(content.substr(colonPos + 1));

            // 根据缩进调整上下文栈
            while (!contextStack.empty() && indent <= contextStack.back().second) {
                contextStack.pop_back();
            }

            // 构建完整键名
            std::string fullKey;
            if (!contextStack.empty()) {
                fullKey = contextStack.back().first + "." + key;
            } else {
                fullKey = key;
            }

            yamlData[fullKey] = value;

            // 如果值为空，可能为父键，压入栈
            if (value.empty()) {
                contextStack.emplace_back(fullKey, indent);
            }
        }
    }

    file.close();
    return yamlData;
}
*/
#endif //YOLOV11_CPP_UTILS_H